package com.example.takeaway.websocket;

import com.example.takeaway.websocket.message.AbstractMessage;
import com.example.takeaway.websocket.message.CloseMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author 邢晨旭
 * {@code @date} 2023/10/26
 * @ServerEndpoint 作用 用来指定一个URI，客户端可以通过这个URI来连接到WebSocket。
 */
@ServerEndpoint(value = "/ws/{uid}", decoders = WsMessageDecoder.class, encoders = WsMessageEncoder.class, configurator = WsConfigurator.class)
@Component
@Slf4j
public class ShopOrderListener {

    private static final ConcurrentHashMap<String, UserSession> SESSIONS = new ConcurrentHashMap<>();

    @OnOpen
    public void onOpen(Session session, EndpointConfig config, @PathParam("uid") String uid) throws IOException {
        if (!(boolean) config.getUserProperties().get("check")) {
            send(session, new CloseMessage("非法链接,请重新登录"));
            session.close();
            return;
        }
        SESSIONS.put(uid, new UserSession(uid, session));
        log.info("客户端{}连接成功", uid);
    }

    @OnClose
    public void onClose(Session session, CloseReason reason, @PathParam("uid") String uid) {
        SESSIONS.remove(uid);
        log.info("客户端{}连接关闭{}", uid, reason.getReasonPhrase());
    }


    @OnMessage
    public void onMessage(Session session, AbstractMessage message, @PathParam("uid") String uid) {
        log.info("收到{}消息{}", uid, message);

    }

    @OnError
    public void onError(Session session, Throwable error, @PathParam("uid") String uid) {
        error.printStackTrace();
        log.error("{}连接异常{}", uid, error.getMessage());
    }

    public static void send(Session session, AbstractMessage message) {
        session.getAsyncRemote().sendObject(message);
    }

    public static void send(String uid, AbstractMessage message) {
        UserSession userSession = SESSIONS.get(uid);
        if (userSession != null) {
            userSession.getSession().getAsyncRemote().sendObject(message);
        }
    }

}
